#pragma once
#include <memory>
#include <map>
#include <string>
#include "client_session.h"


namespace acl
{
namespace mqtt
{
class client_session_manager
{
public:
	static client_session_manager &get_instance ()
	{
		static client_session_manager instance;
		return instance;
	}
	void delete_session (std::string sessionId)
	{
		auto itr = client_sessions_.find (sessionId);
		if (itr != client_sessions_.end ())
			client_sessions_.erase (itr);
	}
	std::shared_ptr<client_session> get_session (std::string sessionId)
	{
		if (sessionId.size () == 0)
			return nullptr;
		auto itr = client_sessions_.find (sessionId);
		if (itr != client_sessions_.end ())
			return itr->second;

		return nullptr;
	}
	void add_session (std::shared_ptr<client_session> _sess)
	{
		if(_sess->get_id().size())
			client_sessions_[_sess->get_id ()] = _sess;
	}

	aio_timer_callback &get_timer_handle ()
	{
		return keepalive_timer_;
	}
private:
	void check_session_alive ()
	{
		for (auto &it : client_sessions_) {
			it.second->check_alive ();
		}
	}

	struct keepalive_timer:aio_timer_callback
	{
		virtual void timer_callback (unsigned int id) override
		{
			(void) id;
			client_session_manager::get_instance ().check_session_alive ();
		}
	};
	keepalive_timer keepalive_timer_;
	client_session_manager (){}
	client_session_manager (const client_session_manager &);
	client_session_manager &operator= (const client_session_manager &);

	
private:
	std::map<std::string, std::shared_ptr<client_session>> client_sessions_;
};
}
}
